<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.10/dist/vue.js"></script>

    <title>学习小目标</title>
  </head>
  <body>
    <div id="app" class="main">
      <h2>小目标列表</h2>
      <div class="list">
        <h3>添加小目标</h3>
        <input
          type="text"
          class="text-keyword"
          placeholder="输入小目标后，按回车确认"
          @keyup.13="addList"
          v-model="addText"
        />
        <!--如果noend等于0，就是全部完成了就显示‘全部完成了’，如果没有就是显示已完成多少条（prolist.length-noend）和未完成多少条（noend）-->
      </div>
      <p>
        共有{{ prolist.length }}个目标，{{ noend == 0 ? "全部完成了" : '已完成'
        + (prolist.length - noend) + '，还有' + noend + '条未完成' }}
      </p>
      <div class="input-select">
        <input
          type="radio"
          name="chooseType"
          checked="true"
          @click="chooseList(1)"
        /><label>所有目标</label>
        <input type="radio" name="chooseType" @click="chooseList(2)" /><label
          >已完成目标</label
        >
        <input type="radio" name="chooseType" @click="chooseList(3)" /><label
          >未完成目标</label
        >
      </div>
      <ul>
        <li
          class="li1"
          v-for="(list,index) in newList"
          :class="{'eidting':curIndex===index}"
        >
          <div>
            <span
              class="status-span"
              @click="changeType(index)"
              :class="{'status-end':list.status}"
            ></span>
            <span @dblclick="curIndex=index">{{ list.name }}</span>
            <span class="close" @click="delectList(list)">X</span>
          </div>
          <input
            type="text"
            class="text2"
            v-model="list.name"
            @keyup.esc="cancelEdit(list)"
            @blur="edited"
            @focus="editBefore(list.name)"
            @keyup.enter="edited"
            v-focus
          />
        </li>
      </ul>
    </div>
  </body>
  <script>
    new Vue({
      el: "#app",
      data: {
        addText: "",
        //name-名称,status-完成状态
        prolist: [
          { name: "HTML5", status: true },
          { name: "CSS3", status: false },
          { name: "vue", status: false },
          { name: "react", status: false },
        ],
        newList: [],
        curIndex: "",
        beforeEditText: "",
        curType: 0,
      },
      computed: {
        //计算属性，返回未完成目标的条数，就是数组里面status=false的条数
        noend: function () {
          return this.prolist.filter(function (item) {
            return !item.status;
          }).length;
        },
      },
      methods: {
        addList() {
          //添加进来默认status=false,就是未完成状态
          this.prolist.push({
            name: this.addText,
            status: false,
          });
          //添加后，清空addText
          this.addText = "";
        },
        chooseList(type) {
          //type=1时，选择所有目标
          //type=2时，选择所有已完成目标
          //type=3时，选择所有未完成目标
          this.curType = type;
          switch (type) {
            case 1:
              this.newList = this.prolist;
              break;
            case 2:
              this.newList = this.prolist.filter(function (item) {
                return item.status;
              });
              break;
            case 3:
              this.newList = this.prolist.filter(function (item) {
                return !item.status;
              });
              break;
          }
        },
        /*改变单条数据的完成状态*/
        changeType(index) {
          this.newList[index].status = !this.newList[index].status;
          //更新数据
          this.chooseList(this.curType);
        },
        delectList(list) {
          var index = this.prolist.indexOf(list);
          //根据索引，删除数组某一项
          this.prolist.splice(index, 1);
          //更新newList  newList可能经过this.prolist.filter()赋值，这样的话，删除了prolist不会影响到newList  那么就要手动更新newList
          //this.newList=this.prolist;
          this.chooseList(this.curType);
        },
        //修改前
        editBefore(name) {
          //先记录当前项（比如这一项，{name:"HTML5",status:false}）
          //beforeEditText="HTML5"
          this.beforeEditText = name;
        },
        //修改完成后
        edited() {
          //修改完了，设置curIndex=""，这样输入框就隐藏，其它元素就会显示。因为在li元素 写了：:class="{'eidting':curIndex===index}"  当curIndex不等于index时，eidting类名就清除了！
          //输入框利用v-model绑定了当前项（比如这一项，{name:"HTML5",status:false}）的name,当在输入框编辑的时候，比如改成‘HTML’,实际上当前项的name已经变成了‘HTML’，所以，这一步只是清除eidting类名，隐藏输入框而已
          //还有一个要注意的就是虽然li遍历的是newList，比如改了newList的这一项（{name:"HTML5",status:false}），比如改成这样（{name:"HTML",status:true}）。实际上prolist的这一项（{name:"HTML5",status:false}），也会被改成（{name:"HTML",status:true}）。因为这里是一个对象，而且公用一个堆栈！修改其中一个，另一个会被影响到
          this.curIndex = "";
        },
        //取消修改
        cancelEdit(val) {
          //上面说了输入框利用v-model绑定了当前项（比如这一项，{name:"HTML5",status:false}）的name,当在输入框编辑的时候，比如改成‘HTML’,实际上当前项的name已经变成了‘HTML’，所以，这一步就是把之前保存的beforeEditText赋值给当前项的name属性，起到一个恢复原来值得作用！
          val.name = this.beforeEditText;
          this.curIndex = "";
        },
      },
      mounted() {
        //初始化，把prolist赋值给newList。默认显示所有目标
        this.newList = this.prolist;
      },

      // 自定义指令
      directives: {
        focus: {
          update(el) {
            el.focus();
          },
        },
      },
    });
  </script>

  <style>
    body {
      font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier,
        monospace;
      font-size: 14px;
    }
    input {
      font-size: 14px;
    }

    body,
    ul,
    div,
    html {
      padding: 0;
      margin: 0;
    }

    .hidden {
      display: none;
    }

    .main {
      width: 800px;
      margin: 0 auto;
    }
    .input-select input {
      cursor: pointer;
    }

    li {
      list-style-type: none;
      line-height: 40px;
      position: relative;
      border: 1px solid transparent;

      padding: 0 20px;
    }

    li .status-span {
      display: block;
      width: 10px;
      height: 10px;
      background: #ccc;
      margin: 14px 10px 0 0;
      float: left;
      cursor: pointer;
    }

    li .status-span.status-end {
      background: #09f;
    }

    li .close {
      position: absolute;
      color: #f00;
      font-size: 20px;
      line-height: 40px;
      height: 40px;
      right: 20px;
      cursor: pointer;
      display: none;
      top: 0;
    }

    li:hover {
      /*border: 1px solid #09f;*/
      background-color: #2b85e4;
    }

    li:hover .close {
      display: block;
    }

    li div {
      display: block;
    }

    li.eidting div {
      display: none;
    }

    li .text2 {
      height: 40px;
      padding-left: 10px;
      box-sizing: border-box;
      margin-left: 10px;
      width: 80%;
      display: none;
    }

    li.eidting .text2 {
      display: block;
    }

    li .text-keyword {
      height: 40px;
      padding-left: 10px;
      box-sizing: border-box;
      margin-left: 10px;
      width: 80%;
      display: none;
    }

    .text-keyword {
      box-sizing: border-box;
      width: 100%;
      height: 40px;
      padding-left: 10px;
      outline: none;
    }
  </style>
</html>
